home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-11-16 | 3.8 KB | 138 lines | [TEXT/MSET] |
- \ The info_run class is used to implement fmt_run and para_run.
- \ An info_run consists of a set of items, each of which starts with a
- \ 4-byte offset (aligned) followed by a number of bytes of information.
- \ This particular number is fixed for each object of this class, but
- \ may vary between objects. It must be even, though.
-
- 0 value STRT \ Used in FIXUP: and MOVE: because we can
- \ only have 5 locals!
-
-
- :class (INFO_RUN) super( bytestring )
-
- int INFOSIZE
-
- :m INFOSIZE: get: infoSize ;m
- :m ITEMSIZE: get: infoSize 4+ ;m
- :m SETINFOSIZE: put: infoSize ;m
-
- :m SKIP_INFO: get: infoSize skip: self ;m
- :m SKIP_ITEM: get: infoSize 4+ skip: self ;m
- :m <SKIP_INFO: get: infoSize negate skip: self ;m
- :m <SKIP_ITEM: get: infoSize 4+ negate skip: self ;m
-
- :m OFFS: ^1st: self @ ;m
-
- :m NEW_ITEM: { offs -- } \ Sets up a new item - all zero initially.
- \ Leaves POS at the info field.
- pad itemSize: self 2dup erase offs pad !
- pos: self 0dup
- IF
- ^1st: self itemSize: self - @ offs =
- THEN
- IF ( same offset as previous entry - overwrite prev entry )
- <skip_item: self ovwr: self
- ELSE
- insert: self
- THEN
- <skip_info: self ;m
-
- :m FIND_POSN: { offs reset? -- }
- reset? IF reset: self THEN
- BEGIN
- len: self 0EXIT
- ^1st: self @ offs > ?EXIT
- skip_item: self
- AGAIN ;m
-
- :m FIXUP: { offs oldlen newlen \ nxt n -- }
-
- \ Makes the necessary adjustments when some text being pointed to by this
- \ info_run is about to be replaced. To save time, we assume that SELF only
- \ has to be scanned from its current position. Remember to RESET: it if
- \ there's any doubt.
-
- pos: self -> strt newlen oldlen - -> n
- nolim: self
- BEGIN \ loop to get up to the place where we have to do anything
- len: self NIF strt >pos: self EXIT THEN
- nxtL: self -> nxt offs nxt >
- WHILE
- skip_info: self
- REPEAT
- BEGIN \ loop to coerce any changes within the old string
- \ to go to the right of the new string
- nxt offs - oldlen <
- WHILE
- newlen offs + -4 skip: self >nxtL: self
- skip_info: self
- len: self NIF strt >pos: self EXIT THEN
- nxtL: self -> nxt
- REPEAT
- BEGIN \ loop to adjust the rest of the offsets
- nxt n + -4 skip: self >nxtL: self
- skip_info: self
- len: self NIF strt >pos: self EXIT THEN
- nxtL: self -> nxt
- AGAIN ;m
-
- ;class
-
- (info_run) TEMP
- objPtr TheIR \ Class will be set to info_run
-
- :class INFO_RUN super( (info_run) )
-
- ' theIR set_to_class info_run
-
- :m MOVE: { pos len trg \ end dist -- }
-
- \ Sets up Self for when some text is to be moved. The text is delimited
- \ by pos and len in the text string, and will be moved to the offset trg.
-
- new: temp infosize: self setinfosize: temp
- pos 1- true find_posn: self pos: self -> strt
- pos len + false find_posn: self pos: self -> end
- strt >pos: self end >lim: self
- ^base ->: temp delete: self nolim: self
- pos len 0 fixup: self
- len --> trg
- trg false find_posn: self
- trg 0 len fixup: self \ For insert
- trg pos - -> dist
- BEGIN
- len: temp
- WHILE
- dist ^1st: temp +!
- skip_item: temp
- REPEAT
- reset: temp temp $insert: self
- \ reset: temp len: temp
- \ IF
- \ nxtL: temp new_item: self
- \ \ We don't just insert as prev item may have same offset
- \ temp $ovwr: self
- \ THEN
- reset: self release: temp ;m
-
- :m CUT: { pos len IRobj \ strt end -- }
- IRobj -> theIR
- infosize: theIR setinfosize: self
- pos 1- true find_posn: theIR pos: theIR -> strt
- pos len + false find_posn: theIR pos: theIR -> end
- strt >pos: theIR end >lim: theIR
- theIR ->: self delete: theIR reset: self nolim: theIR
- pos len 0 fixup: theIR
- 0 pos 0 fixup: self ;m
-
-
- :m PASTE: { pos len IRobj -- }
- IRobj -> theIR reset: theIR
- pos true find_posn: self
- pos 0 len fixup: self \ For insert
- 0 0 pos fixup: theIR
- reset: theIR theIR $insert: self
- reset: self ;m
-
- ;class
-